home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / remote_net.c < prev    next >
C/C++ Source or Header  |  1991-09-18  |  7KB  |  295 lines

  1. /* @(#) $Header: remote_net.c,v 1.10 91/09/17 22:22:04 deyke Exp $ */
  2.  
  3. #include <sys/types.h>
  4.  
  5. #include <ctype.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include <unistd.h>
  10.  
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "timer.h"
  14. #include "transport.h"
  15. #include "hpux.h"
  16. #include "buildsaddr.h"
  17.  
  18. struct controlblock {
  19.   int  fd;                              /* Socket descriptor */
  20.   char  buffer[1024];                   /* Input buffer */
  21.   int  bufcnt;                          /* Number of bytes in buffer */
  22.   struct transport_cb *tp;              /* Transport handle */
  23.   int  binary;                          /* Transfer is binary (no EOL conv) */
  24. };
  25.  
  26. struct cmdtable {
  27.   char  *name;                          /* Command name (lower case) */
  28.   int  (*fnc) __ARGS((struct controlblock *cp)); /* Command function */
  29. };
  30.  
  31. static int  flisten = -1;
  32.  
  33. static char *getarg __ARGS((char *line, int all));
  34. static int command_switcher __ARGS((struct controlblock *cp, char *name, struct cmdtable *tableptr));
  35. static void delete_controlblock __ARGS((struct controlblock *cp));
  36. static void transport_try_send __ARGS((struct controlblock *cp));
  37. static void transport_recv_upcall __ARGS((struct transport_cb *tp, int cnt));
  38. static void transport_send_upcall __ARGS((struct transport_cb *tp, int cnt));
  39. static void transport_state_upcall __ARGS((struct transport_cb *tp));
  40. static int ascii_command __ARGS((struct controlblock *cp));
  41. static int binary_command __ARGS((struct controlblock *cp));
  42. static int connect_command __ARGS((struct controlblock *cp));
  43. static void command_receive __ARGS((struct controlblock *cp));
  44. static void accept_connection __ARGS((void *p));
  45.  
  46. /*---------------------------------------------------------------------------*/
  47.  
  48. static char  *getarg(line, all)
  49. char  *line;
  50. int  all;
  51. {
  52.  
  53.   char  *arg;
  54.   int  c, quote;
  55.   static char  *p;
  56.  
  57.   if (line) p = line;
  58.   while (isspace(uchar(*p))) p++;
  59.   if (all) return p;
  60.   quote = '\0';
  61.   if (*p == '"' || *p == '\'') quote = *p++;
  62.   arg = p;
  63.   if (quote) {
  64.     if (!(p = strchr(p, quote))) p = "";
  65.   } else
  66.     while (*p && !isspace(uchar(*p))) {
  67.       c = tolower(uchar(*p));
  68.       *p++ = c;
  69.     }
  70.   if (*p) *p++ = '\0';
  71.   return arg;
  72. }
  73.  
  74. /*---------------------------------------------------------------------------*/
  75.  
  76. static int  command_switcher(cp, name, tableptr)
  77. struct controlblock *cp;
  78. char  *name;
  79. struct cmdtable *tableptr;
  80. {
  81.   int  namelen;
  82.  
  83.   namelen = strlen(name);
  84.   for (; ; ) {
  85.     if (!tableptr->name) return (-1);
  86.     if (!strncmp(tableptr->name, name, namelen)) return (*tableptr->fnc)(cp);
  87.     tableptr++;
  88.   }
  89. }
  90.  
  91. /*---------------------------------------------------------------------------*/
  92.  
  93. static void delete_controlblock(cp)
  94. struct controlblock *cp;
  95. {
  96.   off_read(cp->fd);
  97.   close(cp->fd);
  98.   free(cp);
  99. }
  100.  
  101. /*---------------------------------------------------------------------------*/
  102.  
  103. static void transport_try_send(cp)
  104. struct controlblock *cp;
  105. {
  106.  
  107.   int  cnt;
  108.   struct mbuf *bp;
  109.  
  110.   cnt = transport_send_space(cp->tp);
  111.   if (cnt <= 0) {
  112.     off_read(cp->fd);
  113.     return;
  114.   }
  115.   if (!(bp = alloc_mbuf(cnt))) return;
  116.   cnt = read(cp->fd, bp->data, (unsigned) cnt);
  117.   if (cnt <= 0) {
  118.     free_p(bp);
  119.     off_read(cp->fd);
  120.     transport_close(cp->tp);
  121.     return;
  122.   }
  123.   bp->cnt = cnt;
  124.   transport_send(cp->tp, bp);
  125. }
  126.  
  127. /*---------------------------------------------------------------------------*/
  128.  
  129. static void transport_recv_upcall(tp, cnt)
  130. struct transport_cb *tp;
  131. int16 cnt;
  132. {
  133.  
  134.   char  buffer[1024];
  135.   struct controlblock *cp;
  136.   struct mbuf *bp;
  137.  
  138.   cp = (struct controlblock *) tp->user;
  139.   transport_recv(tp, &bp, 0);
  140.   while ((cnt = pullup(&bp, buffer, sizeof(buffer))) > 0)
  141.     if (write(cp->fd, buffer, (unsigned) cnt) != cnt) transport_close(tp);
  142. }
  143.  
  144. /*---------------------------------------------------------------------------*/
  145.  
  146. static void transport_send_upcall(tp, cnt)
  147. struct transport_cb *tp;
  148. int16 cnt;
  149. {
  150.   struct controlblock *cp;
  151.  
  152.   cp = (struct controlblock *) tp->user;
  153.   on_read(cp->fd, (void (*)()) transport_try_send, cp);
  154. }
  155.  
  156. /*---------------------------------------------------------------------------*/
  157.  
  158. static void transport_state_upcall(tp)
  159. struct transport_cb *tp;
  160. {
  161.   delete_controlblock((struct controlblock *) tp->user);
  162.   transport_del(tp);
  163. }
  164.  
  165. /*---------------------------------------------------------------------------*/
  166.  
  167. static int  ascii_command(cp)
  168. struct controlblock *cp;
  169. {
  170.   cp->binary = 0;
  171.   return 0;
  172. }
  173.  
  174. /*---------------------------------------------------------------------------*/
  175.  
  176. static int  binary_command(cp)
  177. struct controlblock *cp;
  178. {
  179.   cp->binary = 1;
  180.   return 0;
  181. }
  182.  
  183. /*---------------------------------------------------------------------------*/
  184.  
  185. static int  connect_command(cp)
  186. struct controlblock *cp;
  187. {
  188.   char  *protocol, *address;
  189.  
  190.   protocol = getarg((char *) 0, 0);
  191.   address = getarg((char *) 0, 1);
  192.   cp->tp = transport_open(protocol, address, transport_recv_upcall, transport_send_upcall, transport_state_upcall, (char *) cp);
  193.   if (!cp->tp) return (-1);
  194.   if (!cp->binary) {
  195.     cp->tp->recv_mode = EOL_LF;
  196.     cp->tp->send_mode = (!strcmp(protocol, "tcp")) ? EOL_CRLF : EOL_CR;
  197.   }
  198.   on_read(cp->fd, (void (*)()) transport_try_send, cp);
  199.   return 0;
  200. }
  201.  
  202. /*---------------------------------------------------------------------------*/
  203.  
  204. static void command_receive(cp)
  205. struct controlblock *cp;
  206. {
  207.  
  208.   static struct cmdtable command_table[] = {
  209.     "ascii",   ascii_command,
  210.     "binary",  binary_command,
  211.     "connect", connect_command,
  212.     0,         0
  213.   };
  214.  
  215.   char  c;
  216.  
  217.   if (read(cp->fd, &c, 1) <= 0) {
  218.     delete_controlblock(cp);
  219.     return;
  220.   }
  221.   if (c != '\n') {
  222.     cp->buffer[cp->bufcnt++] = c;
  223.     if (cp->bufcnt >= sizeof(cp->buffer)) delete_controlblock(cp);
  224.     return;
  225.   }
  226.   cp->buffer[cp->bufcnt] = '\0';
  227.   cp->bufcnt = 0;
  228.   if (command_switcher(cp, getarg(cp->buffer, 0), command_table))
  229.     delete_controlblock(cp);
  230. }
  231.  
  232. /*---------------------------------------------------------------------------*/
  233.  
  234. static void accept_connection(p)
  235. void *p;
  236. {
  237.  
  238.   int  addrlen;
  239.   int  fd;
  240.   struct controlblock *cp;
  241.   struct sockaddr addr;
  242.  
  243.   addrlen = sizeof(addr);
  244.   if ((fd = accept(flisten, &addr, &addrlen)) < 0) return;
  245.   cp = (struct controlblock *) calloc(1, sizeof (struct controlblock ));
  246.   if (!cp) {
  247.     close(fd);
  248.     return;
  249.   }
  250.   cp->fd = fd;
  251.   on_read(cp->fd, (void (*)()) command_receive, cp);
  252. }
  253.  
  254. /*---------------------------------------------------------------------------*/
  255.  
  256. void remote_net_initialize()
  257. {
  258.  
  259.   static char  *socketnames[] = {
  260. #if (defined(hpux)||defined(__hpux))
  261.     "unix:/tcp/.sockets/netcmd",
  262. #else
  263.     "*:4718",
  264. #endif
  265.     (char *) 0
  266.   };
  267.  
  268.   int  addrlen, i;
  269.   int  arg;
  270.   struct sockaddr *addr;
  271.  
  272.   for (i = 0; socketnames[i]; i++) {
  273.     if (addr = build_sockaddr(socketnames[i], &addrlen)) {
  274.       if ((flisten = socket(addr->sa_family, SOCK_STREAM, 0)) >= 0) {
  275.     switch (addr->sa_family) {
  276.     case AF_UNIX:
  277.       if (!Debug) unlink(addr->sa_data);
  278.       break;
  279.     case AF_INET:
  280.       arg = 1;
  281.       setsockopt(flisten, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
  282.       break;
  283.     }
  284.     if (!bind(flisten, addr, addrlen) && !listen(flisten, SOMAXCONN)) {
  285.       on_read(flisten, accept_connection, (void *) 0);
  286.     } else {
  287.       close(flisten);
  288.       flisten = -1;
  289.     }
  290.       }
  291.     }
  292.   }
  293. }
  294.  
  295.